﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Business
{
    public class PrintOrderDetail
    {
        public long OrderID { get; set; }
        public DateTime OrderTime { get; set; }
        public string OrderBy { get; set; }
        public DateTime PickUpDateTime { get; set; }
        public string OrderRemark { get; set; }
        public int FoodQuantity { get; set; }
        public decimal FoodPrice { get; set; }
        public string Condiment { get; set; }
        public string FoodName { get; set; }
        public string Caterer { get; set; }
        public string PrinterName { get; set; }
    }
    public class Order
    {
        FosIntelEntities _en = new FosIntelEntities();

        public string ConfirmOrder(List<Cart> items, string remarks, DateTime pickupdatetime, User user)
        {
            fos_Order order = new fos_Order();
            order.CreatedBy = user.email;
            order.CreatedDate = DateTime.Now;
            order.LastModifiedDate = DateTime.Now;
            order.IsDeleted = 0;
            order.LastModifiedBy = user.email;

            order.OrderBy = user.id;
            order.PickUpDateTime = pickupdatetime;
            order.Remark = remarks;
            order.IsCancel = 0;

            List<fos_orderdetails> listItems = new List<fos_orderdetails>();
            listItems = ConvertCart2OrderDetails(items);
            foreach (fos_orderdetails item in listItems)
            {
                item.IsPickup = true;
                order.fos_orderdetails.Add(item);

            }

            _en.fos_Order.Add(order);
            _en.SaveChanges();

            PrinterManagement pm = new PrinterManagement();
            //pm.PrinterPrintString(pm.PrintOrder(order));

            SeparateOrderByCatererNPrint(order);
            return order.Id.ToString();
        }


        public List<fos_orderdetails> ConvertCart2OrderDetails(List<Cart> items)
        {
            List<fos_orderdetails> orderdetails = new List<fos_orderdetails>();
            System.Collections.Generic.HashSet<fos_orderdetails> a = new System.Collections.Generic.HashSet<fos_orderdetails>();
            
            foreach (Cart item in items)
            {
                fos_orderdetails detail = new fos_orderdetails();
                detail.FoodId = item.FoodId;
                detail.FoodName = item.name;
                detail.FoodPrice = item.price;
                detail.FoodQuantity = item.quantity;
                detail.Condiment = item.condiment;
                orderdetails.Add(detail);

            }
            return orderdetails;


        }


        public fos_Order[] GetOrderByUserId(long userId)
        {
           fos_Order[] myOrder = (from a in _en.fos_Order
                                       where a.OrderBy == userId
                                       orderby a.Id descending
                                       select a).ToArray<fos_Order>();
            return myOrder;


        }

        public void CancelOrder(long orderId)
        {
            fos_Order myOrder = (from a in _en.fos_Order
                                 where a.Id == orderId
                                 select a).FirstOrDefault();
            fos_Setting settings = (from a in _en.fos_Setting
                                    where a.Id == 1
                                    select a).FirstOrDefault();
            DateTime currentDateTime = DateTime.Now;
            DateTime myPickupDateTime = (DateTime)myOrder.PickUpDateTime;
            // If pickup time is after current time, cannot cancel order
            if (myPickupDateTime <= currentDateTime)
                throw new Exception("You can no longer cancel this order! It is already over!");
            else  // else, you may cancel
            {
                // as long as not on same date and current time not exceeding preset time
                //replace : to . then convert to double
                string Cutofftime = settings.ParamValue.Replace(":", ".");
                double time = Convert.ToDouble(Cutofftime);
                if (Convert.ToDouble(currentDateTime.Hour) > time && myPickupDateTime.Date == currentDateTime.Date)
                {
                    throw new Exception("You can no longer cancel your order! It already exceed the cut off time!");

                }
                else
                {
                    myOrder.IsCancel = 1;
                    myOrder.CancelDateTime = DateTime.Now;
                    _en.SaveChanges();
                }
            }



        }




        public List<fos_orderdetails> GetOrderDetailsByCaterer(string email)
        {
            List<fos_orderdetails> orderdetails = (from a in _en.fos_orderdetails
                                                   where a.fos_Food.CreatedBy == email
                                                   select a).ToList<fos_orderdetails>();



            return orderdetails;


        }


        public void UpdateOrderDetailPickup(long orderdetailId, bool isPickup)
        {
            fos_orderdetails data = (from a in _en.fos_orderdetails
                                     where a.Id == orderdetailId
                                     select a).FirstOrDefault();

            data.IsPickup = isPickup;
            _en.SaveChanges();
        }

        public void SeparateOrderByCatererNPrint(fos_Order order)
        {
            // Retrieve all the order details including the printer name
            List<PrintOrderDetail> pds = new List<PrintOrderDetail>();
            pds = (from fo in _en.fos_Order
                   join fod in _en.fos_orderdetails on fo.Id equals fod.OrderID
                   join u in _en.fos_User on fo.OrderBy equals u.Id
                   join fd in _en.fos_Food on fod.FoodId equals fd.Id
                   join u2 in _en.fos_User on fd.CreatedBy equals u2.Email
                   join slp in _en.fos_SiteLinkPrinter on u2.Id equals slp.UserId
                   join pr in _en.fos_Printer on slp.PrinterId equals pr.Id
                   where (slp.IsDeleted != 1 || slp.IsDeleted == null) && fo.Id == order.Id
                   select new PrintOrderDetail
              {
                  OrderID = fo.Id,
                  OrderTime = fo.CreatedDate,
                  OrderBy = u.Email,
                  PickUpDateTime = (DateTime)fo.PickUpDateTime,
                  OrderRemark = fo.Remark,
                  FoodQuantity = (int)fod.FoodQuantity,
                  FoodPrice = (decimal)fod.FoodPrice,
                  Condiment = fod.Condiment,
                  FoodName = fod.FoodName,
                  Caterer = fd.CreatedBy,
                  PrinterName = pr.PrinterName
              }).ToList<PrintOrderDetail>();


            // group according to PrinterName
            var queryPrinter =
                from pOrderDetail in pds
                group pOrderDetail by pOrderDetail.PrinterName into newGroup
                orderby newGroup.Key
                select newGroup;

            // iterate each group and send print job
            foreach (var nameGroup in queryPrinter)
            {
                //System.Diagnostics.Debug.WriteLine(nameGroup.Key);
                // construct setence,                
                // send jobs
                string PrinterName = nameGroup.Key;
                PrinterManagement pm = new PrinterManagement();
                pm.PrintSentences(pm.PrintOrderSentenceUpdate(nameGroup), PrinterName);

            }
        }
    }
}
